home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-10-14 | 39.6 KB | 1,213 lines |
- Newsgroups: comp.sources.misc
- X-UNIX-From: dvadura@watdragon.waterloo.edu
- subject: v15i058: dmake version 3.6 (part 06/25)
- from: Dennis Vadura <dvadura@watdragon.waterloo.edu>
- Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
-
- Posting-number: Volume 15, Issue 58
- Submitted-by: Dennis Vadura <dvadura@watdragon.waterloo.edu>
- Archive-name: dmake-3.6/part06
-
- #!/bin/sh
- # this is part 6 of a multipart archive
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file rulparse.c continued
- #
- CurArch=6
- if test ! -r s2_seq_.tmp
- then echo "Please unpack part 1 first!"
- exit 1; fi
- ( read Scheck
- if test "$Scheck" != $CurArch
- then echo "Please unpack part $Scheck next!"
- exit 1;
- else exit 0; fi
- ) < s2_seq_.tmp || exit 1
- echo "x - Continuing file rulparse.c"
- sed 's/^X//' << 'SHAR_EOF' >> rulparse.c
- X * get marked as having rules and being a target if appropriate. */
- X do {
- X tcp->ce_flag |= tg->ce_flag & (F_RULES|F_TARGET);
- X tcp = tcp->ce_all;
- X }
- X while( tcp != tg );
- X break;
- X }
- X }
- X
- X if( tflag ) Target = TRUE;
- X _sv_rules = NIL(STRING);
- X _sv_crule = NIL(STRING);
- X _sv_targets = NIL(CELL);
- X _sv_glb_prq = NIL(LINK);
- X _sv_edgel = NIL(EDGE);
- X _sp_target = FALSE;
- X _sv_globprq_only = 0;
- X
- X DB_VOID_RETURN;
- X}
- X
- X
- X
- Xint
- XSet_group_attributes( list )/*
- X==============================
- X Scan list looking for the standard @ and - (as in recipe line defs)
- X and set the flags accordingly so that they apply when we bind the
- X rules to the appropriate targets. */
- Xchar *list;
- X{
- X t_attr attr = 0;
- X int done = FALSE;
- X int res = FALSE;
- X
- X DB_ENTER( "Set_group_attributes" );
- X
- X while( !done )
- X switch( *list++ ) {
- X case '@' : attr |= A_SILENT; ;break;
- X case '-' : attr |= A_IGNORE; ;break;
- X case '%' : attr |= A_SWAP; ;break;
- X
- X case ' ' :
- X case '+' :
- X case '\t': break;
- X
- X case '\0': done = TRUE; break;
- X case '[' : res = TRUE; break;
- X
- X default : done = TRUE; res = FALSE; break;
- X }
- X
- X if( res ) _sv_attr |= attr;
- X DB_RETURN( res );
- X}
- X
- X
- X
- Xstatic void
- X_do_special( special, op, attr, set_dir, target, prereq, state )/*
- X==================================================================
- X Process a special target. So far the only special targets we have
- X are those recognized by the _is_special function.
- X
- X target is always only a single special target.
- X
- X NOTE: For the cases of .IMPORT, and .INCLUDE, the cells created by the
- X parser are never freed. This is due to the fact that it is too much
- X trouble to get them out of the hash table once they are defined, and
- X if they are per chance used again it will be ok, anyway, since the
- X cell is not really used by the code below. */
- X
- Xint special;
- Xint op;
- Xt_attr attr;
- Xchar *set_dir;
- XCELLPTR target;
- XCELLPTR prereq;
- Xint *state;
- X{
- X HASHPTR hp; /* pointer to macro def cell */
- X CELLPTR cp; /* temporary pointer into cells list */
- X CELLPTR dp; /* pointer to directory dir cell */
- X LINKPTR lp; /* pointer at prerequisite list */
- X char *dir; /* current dir to prepend */
- X char *path; /* resulting path to try to read */
- X char *name; /* File name for processing a .INCLUDE */
- X char *tmp; /* temporary string pointer */
- X FILE *fil; /* File descriptor returned by Openfile */
- X
- X DB_ENTER( "_do_special" );
- X
- X target->ce_flag = F_SPECIAL; /* mark the target as special */
- X
- X switch( special ) {
- X case ST_EXPORT:
- X for( ; prereq != NIL(CELL); prereq = prereq->ce_link ) {
- X DB_PRINT( "par", ("Exporting [%s]", prereq->CE_NAME) );
- X hp = GET_MACRO( prereq->CE_NAME );
- X
- X if( hp != NIL(HASH) ) {
- X char *tmpstr = hp->ht_value;
- X
- X if( tmpstr == NIL(char) ) tmpstr = "";
- X
- X if( Write_env_string( prereq->CE_NAME, tmpstr ) != 0 )
- X Warning( "Could not export %s", prereq->CE_NAME );
- X }
- X }
- X break;
- X
- X case ST_IMPORT:
- X if( prereq != NIL(CELL) && prereq->ce_link == NIL(CELL) &&
- X strcmp(prereq->CE_NAME, ".EVERYTHING") == 0 )
- X {
- X ReadEnvironment();
- X }
- X else {
- X char *tmpstr;
- X
- X for( ; prereq != NIL(CELL); prereq = prereq->ce_link ) {
- X DB_PRINT( "par", ("Importing [%s]", prereq->CE_NAME) );
- X
- X tmpstr = Read_env_string( prereq->CE_NAME );
- X
- X if( tmpstr != NIL(char) )
- X Def_macro( prereq->CE_NAME, tmpstr, M_EXPANDED | M_LITERAL );
- X else
- X if( !((Glob_attr | attr) & A_IGNORE) )
- X Fatal( "Imported macro `%s' not found", prereq->CE_NAME );
- X }
- X
- X attr &= ~A_IGNORE;
- X }
- X break;
- X
- X case ST_INCLUDE:
- X {
- X int ignore = (((Glob_attr | attr) & A_IGNORE) != 0);
- X int pushed = FALSE;
- X CELL inc;
- X HASH hcell;
- X
- X if( prereq == NIL(CELL) ) Fatal( "No .INCLUDE file(s) specified" );
- X
- X dp = Def_cell( ".INCLUDEDIRS", NIL(CELL) );
- X
- X if( (attr & A_SETDIR) && *(dir = strchr(set_dir, '=')+1) ) {
- X hcell.ht_name = ".INCLUDE";
- X inc.ce_name = &hcell;
- X inc.ce_dir = dir;
- X pushed = Push_dir( &inc, ignore );
- X }
- X
- X for( cp=prereq; cp != NIL(CELL); cp = cp->ce_link ) {
- X name = cp->CE_NAME;
- X
- X if( *name == '<' ) {
- X /* We have a file name enclosed in <....>
- X * so get rid of the <> arround the file name */
- X
- X name++;
- X if( (tmp = strrchr( name, '>' )) != NIL( char ) )
- X *tmp = 0;
- X
- X if( If_root_path( name ) )
- X fil = Openfile( name, FALSE );
- X else
- X fil = NIL(FILE);
- X }
- X else
- X fil = Openfile( name, FALSE );
- X
- X if( fil == NIL(FILE) ) { /*if true ==> not found in current dir*/
- X /* Now we must scan the list of prerequisites for .INCLUDEDIRS
- X * looking for the file in each of the specified directories.
- X * if we don't find it then we issue an error. The error
- X * message is suppressed if the .IGNORE attribute of attr is
- X * set. If a file is found we call Parse on the file to
- X * perform the parse and then continue on from where we left
- X * off. */
- X
- X if( (dp->CE_HOW != NIL(HOW)) &&
- X ((lp = dp->CE_HOW->hw_prq) != NIL(LINK)) )
- X for(; lp != NIL(LINK) && fil == NIL(FILE); lp=lp->cl_next) {
- X dir = lp->cl_prq->CE_NAME;
- X if( strchr(dir, '$') ) dir = Expand(dir);
- X path = Build_path( dir, name );
- X
- X DB_PRINT( "par", ("Trying to include [%s]", path) );
- X
- X fil = Openfile( path, FALSE );
- X if( dir != lp->cl_prq->CE_NAME ) FREE(dir);
- X }
- X }
- X
- X if( fil != NIL(FILE) )
- X Parse( fil );
- X else if( !((Glob_attr | attr) & A_IGNORE) )
- X Fatal( "Include file %s, not found", name );
- X }
- X
- X if( pushed ) Pop_dir(FALSE);
- X attr &= ~(A_IGNORE|A_SETDIR);
- X }
- X break;
- X
- X case ST_SOURCE:
- X /* case ST_SUFFIXES: */
- X if( prereq != NIL(CELL) )
- X _do_targets( op & (R_OP_CL | R_OP_MI | R_OP_UP), attr, set_dir,
- X target, prereq );
- X else {
- X /* The old semantics of .SOURCE were that an empty list of
- X * prerequisites clears the .SOURCE list. So we must implement
- X * that here as a clearout prerequisite operation. Since this is
- X * a standard operation with the :- opcode we can simply call the
- X * proper routine with the target cell and it should do the trick
- X */
- X
- X if( op == R_OP_CL || (op & R_OP_MI) )
- X Clear_prerequisites( target->CE_HOW );
- X }
- X
- X op &= ~(R_OP_MI | R_OP_UP);
- X break;
- X
- X case ST_REST:
- X /* The rest of the special targets can all take rules, as such they
- X * must be able to affect the state of the parser. */
- X
- X {
- X int s_targ = Target;
- X
- X Target = TRUE;
- X _sp_target = TRUE;
- X *state = _do_targets( op, attr, set_dir, target, prereq );
- X Target = s_targ;
- X
- X set_dir = NIL( char );
- X attr = A_DEFAULT;
- X op = R_OP_CL;
- X }
- X break;
- X
- X default:break;
- X }
- X
- X if( set_dir != NIL(char) ) FREE( set_dir );
- X if( op != R_OP_CL ) Warning( "Modifier(s) for operator ignored" );
- X if( attr != A_DEFAULT ) Warning( "Extra attributes ignored" );
- X
- X DB_VOID_RETURN;
- X}
- X
- X
- X
- Xstatic int
- X_do_targets( op, attr, set_dir, targets, prereq )/*
- X================================================= */
- Xint op;
- Xt_attr attr;
- Xchar *set_dir;
- XCELLPTR targets;
- XCELLPTR prereq;
- X{
- X CELLPTR tg1; /* temporary target pointer */
- X CELLPTR tp1; /* temporary prerequisite pointer */
- X char *p; /* temporary char pointer */
- X CELLPTR prev_cell; /* pointer for .UPDATEALL processing */
- X int update; /* A_UPDATEALL attribute flag */
- X int smagic = 0; /* collective amount of magic :-) */
- X
- X DB_ENTER( "_do_targets" );
- X
- X if( update = ((attr & A_UPDATEALL) != 0) )
- X if( targets == NIL(CELL) )
- X Fatal( ".UPDATEALL attribute requires non-empty list of targets" );
- X
- X prev_cell = NIL(CELL);
- X for( tg1 = targets; tg1 != NIL(CELL); tg1 = tg1->ce_link ) {
- X /* Check each target. Check for inconsistencies between :: and : rule
- X * sets. :: may follow either : or :: but not the reverse. We allocate
- X * a HOW cell for each target that we see, if it already does not have
- X * one. If it has a HOW cell then we use it, unless the current
- X * operator is ::, in which case we must allocate a new one. */
- X
- X int magic = (tg1->ce_flag & F_PERCENT) && !(tg1->ce_flag & F_MAGIC);
- X smagic |= magic;
- X
- X if( !(op & R_OP_DCL ) && (tg1->ce_flag & F_MULTI) && !magic )
- X Fatal( "Inconsistency in inference rules for %s", tg1->CE_NAME );
- X
- X if( magic )
- X do {
- X _build_graph( op, tg1, prereq );
- X if( prereq != NIL(CELL) ) prereq = prereq->ce_link;
- X } while( prereq != NIL(CELL) );
- X else if( !(tg1->ce_flag & F_SPECIAL) &&
- X (p = _is_magic( tg1->CE_NAME )) != NIL(char) )
- X smagic |= _do_magic( op, p, tg1, prereq, attr, set_dir );
- X else if( op & R_OP_DCL ) {
- X HOWPTR hp;
- X
- X TALLOC( hp, 1, HOW );
- X
- X hp->hw_next = tg1->CE_HOW;
- X tg1->CE_HOW = hp;
- X tg1->ce_flag |= F_MULTI;
- X }
- X else if( tg1->CE_HOW == NIL(HOW) )
- X TALLOC( tg1->CE_HOW, 1, HOW );
- X
- X if( !magic ) _set_attributes( attr, set_dir, tg1 );
- X
- X if( update ) {
- X if( smagic ) Fatal( ".UPDATEALL attribute not legal in meta rule" );
- X
- X /* Check this as it would break another cirlcular .UPATEALL list if
- X * we blindly assign it and it is part of another list already. */
- X if( tg1->ce_all != NIL(CELL) )
- X Fatal( "Target [%s] appears on multiple .UPDATEALL lists" );
- X
- X tg1->ce_all = prev_cell;
- X prev_cell = tg1;
- X }
- X
- X /* Build the proper prerequisite list of the target. If the `-',
- X * modifier was used clear the prerequisite list before adding any
- X * new prerequisites. Else add them to the head/tail as appropriate.
- X *
- X * If the target has F_PERCENT set then no prerequisites are used. */
- X
- X if( !(tg1->ce_flag & F_PERCENT) )
- X if( tg1 == targets || !update ) {
- X register HOWPTR how = tg1->CE_HOW;
- X
- X if( op & R_OP_MI ) Clear_prerequisites( how );
- X
- X if( (op & R_OP_UP) && (how->hw_prq != NIL(LINK)) )
- X _stick_at_head( how, prereq );
- X else
- X for( tp1=prereq; tp1 != NIL(CELL); tp1 = tp1->ce_link )
- X Add_prerequisite( how, tp1, FALSE );
- X }
- X else
- X if( op & (R_OP_MI | R_OP_UP) )
- X Warning( "Modifier(s) `^!' for ':' operator ignored" );
- X }
- X
- X if( targets != NIL(CELL) ) targets->ce_all = prev_cell;
- X
- X
- X /* Check to see if we have NO targets but some attributes. IF so then
- X * apply all of the attributes to the complete list of prerequisites.
- X * Cannot happen for F_PERCENT targets. (ie. in that case targets is always
- X * not NIL) */
- X
- X if( (targets == NIL(CELL)) && attr )
- X if( prereq != NIL(CELL) )
- X for( tp1=prereq; tp1 != NIL(CELL); tp1 = tp1->ce_link ) {
- X if( tp1->CE_HOW == NIL(HOW) ) TALLOC( tp1->CE_HOW, 1, HOW );
- X _set_attributes( attr, set_dir, tp1 );
- X }
- X else
- X _set_global_attr( attr, set_dir );
- X
- X /* Fix up the HOW pointers for the A_UPDATEALL case, they should all point
- X * to the same cell (targets->CE_HOW), if the .UPDATEALL attribute is given
- X */
- X if( update && targets != NIL(CELL) )
- X for( tg1=targets->ce_link; tg1 != NIL(CELL); tg1 = tg1->ce_link ) {
- X FREE(tg1->CE_HOW);
- X tg1->CE_HOW = targets->CE_HOW;
- X }
- X
- X /* Now that we have built the lists of targets, the parser must parse the
- X * rules if there are any. However we must start the rule list with the
- X * rule specified as via the ; kludge, if there is one */
- X
- X _sv_targets = targets;
- X _sv_attr = _sv_attro = attr;
- X _sv_flag = ((op & R_OP_BG) ? F_SINGLE : F_DEFAULT);
- X
- X DB_RETURN( RULE_SCAN );
- X}
- X
- X
- Xstatic int
- X_do_magic( op, dot, target, prereq, attr, set_dir )/*
- X=====================================================
- X This function takes a magic target of the form .<chars>.<chars> or
- X .<chars> and builds the appropriate % rules for that target.
- X
- X The function builds the % rule, `%.o : %.c' from .c.o, and
- X `%.a :' from .a */
- X
- Xint op;
- Xchar *dot;
- XCELLPTR target;
- XCELLPTR prereq;
- Xt_attr attr;
- Xchar *set_dir;
- X{
- X CELLPTR tg;
- X CELLPTR prq;
- X char *tmp, *tmp2;
- X
- X DB_ENTER( "_do_magic" );
- X
- X if( prereq != NIL(CELL) )
- X Warning( "Ignoring prerequisites of old style meta-target" );
- X
- X op &= (R_OP_CL | R_OP_DCL);
- X
- X if( dot == target->CE_NAME ) { /* its of the form .a */
- X tg = Def_cell( "%", NIL(CELL) ); /* ==> no prerequisite */
- X tmp = _build_meta( target->CE_NAME );
- X prq = Def_cell( tmp, NIL(CELL) );
- X FREE( tmp );
- X
- X _build_graph( op, tg, prq );
- X }
- X else {
- X tmp = _build_meta( dot );
- X tg = Def_cell( tmp, NIL(CELL) );
- X FREE( tmp );
- X
- X tmp = _build_meta( tmp2 = _substr( target->CE_NAME, dot ) );
- X prq = Def_cell( tmp, NIL(CELL) );
- X FREE( tmp );
- X FREE( tmp2 );
- X
- X _build_graph( op, tg, prq );
- X }
- X
- X tg->ce_flag |= F_PERCENT;
- X target->ce_flag |= (tg->ce_flag & (F_MULTI | F_PERCENT)) | F_MAGIC;
- X target->CE_EDGES = tg->CE_EDGES;
- X
- X _set_attributes( attr, set_dir, tg );
- X
- X DB_RETURN(1);
- X}
- X
- X
- X
- Xstatic char *
- X_build_meta( name )/*
- X=====================
- X Check to see if the name is of the form .c~ if so and if Augmake
- X translation is enabled then return s.%.c, else return %.suff, where if the
- X suffix ends in '~' then leave it be.*/
- Xchar *name;
- X{
- X char *tmp;
- X int test = Augmake ? name[strlen(name)-1] == '~' : 0;
- X
- X tmp = _strjoin( test ? "s.%" : "%", name, -1, FALSE);
- X if( test ) tmp[ strlen(tmp)-1 ] = '\0';
- X
- X return(tmp);
- X}
- X
- X
- X
- Xstatic void
- X_build_graph( op, target, prereq )/*
- X====================================
- X This function is called to build the graph for the % rule given by
- X target : prereq cell combination. This function assumes that target
- X is a % target and that prereq is a single % prerequisite. op can be
- X either R_OP_CL or R_OP_DCL, all other operations are ignored.
- X
- X It also assumes that target cell has F_PERCENT set already. */
- Xint op;
- XCELLPTR target;
- XCELLPTR prereq;
- X{
- X int match;
- X EDGEPTR edge;
- X
- X DB_ENTER( "_build_graph" );
- X DB_PRINT( "%", ("Building graph for [%s : %s]", target->CE_NAME,
- X (prereq == NIL(CELL)) ? "" : prereq->CE_NAME) );
- X
- X if( prereq != NIL(CELL) ) {
- X char *name = prereq->CE_NAME;
- X int len = strlen(name);
- X
- X if( *name == '\'' && name[len-1]=='\'' ){
- X _add_global_prereq( prereq );
- X name[len-1] = '\0';
- X strcpy(name, name+1);
- X DB_VOID_RETURN;
- X }
- X }
- X
- X /* The list of edges is kept as a circular list. Thus we must find the
- X * last edge if we are to add a new edge. Also we must check the list to
- X * find out if a new edge needs to be added. */
- X
- X match = FALSE;
- X if( (edge = target->CE_EDGES) != NIL(EDGE) ) {
- X EDGEPTR start;
- X
- X start = edge;
- X do {
- X DB_PRINT( "%", ("Trying to match [%s]", edge->ed_prq->CE_NAME) );
- X
- X if( edge->ed_prq == prereq )
- X match = TRUE;
- X else
- X edge = edge->ed_next;
- X }
- X while ( !match && start != edge );
- X }
- X
- X if( match ) {
- X /* match is TRUE hence, we found an edge joining the target and the
- X * prerequisite so set the current target's CE_EDGES pointer to point
- X * at the edge we found and make sure the new edge has a valid HOW
- X * pointer. */
- X
- X DB_PRINT( "%", ("It's an old edge") );
- X
- X target->CE_EDGES = edge;
- X
- X if( op & R_OP_DCL ) {
- X HOWPTR hp;
- X
- X TALLOC( hp, 1, HOW );
- X
- X hp->hw_next = edge->ed_how;
- X edge->ed_how = hp;
- X }
- X else {
- X HOWPTR hp = edge->ed_how;
- X
- X hp->hw_flag = F_DEFAULT;
- X hp->hw_attr = A_DEFAULT;
- X target->ce_dir = NIL(char);
- X target->ce_flag &= (F_PERCENT|F_MAGIC);
- X target->ce_attr &= A_NOINFER;
- X }
- X
- X }
- X else {
- X EDGEPTR tedge;
- X
- X TALLOC( tedge, 1, EDGE );
- X
- X if( edge == NIL(EDGE) ) {
- X DB_PRINT( "%", ("It's a new edge") );
- X edge = tedge;
- X target->CE_EDGES = edge->ed_next = edge;
- X }
- X else {
- X DB_PRINT( "%", ("It's a new edge (non-empty edge list)") );
- X tedge->ed_next = edge->ed_next;
- X edge->ed_next = tedge;
- X target->CE_EDGES = edge = tedge;
- X }
- X
- X /* This was a new edge so we must point it's prerequisite pointer at the
- X * prerequisite, and add the first HOW cell.
- X * Since this is also the first time we have seen the % target we
- X * add it to the NFA we are building of % rule targets. */
- X
- X TALLOC( edge->ed_how, 1, HOW );
- X
- X edge->ed_prq = prereq;
- X edge->ed_tg = target;
- X
- X if( !(target->ce_flag & F_DFA) ) {
- X Add_nfa( target->CE_NAME );
- X target->ce_flag |= F_DFA;
- X }
- X
- X if( op & R_OP_DCL ) target->ce_flag |= F_MULTI;
- X }
- X
- X edge->ed_link = _sv_edgel;
- X _sv_edgel = edge;
- X _sv_globprq_only = 0;
- X
- X DB_VOID_RETURN;
- X}
- X
- X
- X
- Xstatic void
- X_add_global_prereq( pq )/*
- X==========================
- X Prerequisite is a non-% prerequisite for a %-rule target, add it to
- X the target's list of global prerequsites to add on match */
- XCELLPTR pq;
- X{
- X register LINKPTR ln;
- X
- X TALLOC( ln, 1, LINK );
- X ln->cl_next = _sv_glb_prq;
- X ln->cl_prq = pq;
- X _sv_glb_prq = ln;
- X}
- X
- X
- X
- Xstatic void
- X_set_attributes( attr, set_dir, cell )/*
- X=============================================
- X Set the appropriate attributes for a cell */
- Xt_attr attr;
- Xchar *set_dir;
- XCELLPTR cell;
- X{
- X char *dir;
- X
- X DB_ENTER( "_set_attributes" );
- X
- X /* If .SETDIR attribute is set then we have at least .SETDIR= in the
- X * set_dir string. So go and fishout what is at the end of the =.
- X * If not set and not NULL then propagate it to the target cell. */
- X
- X if( attr & A_SETDIR ) {
- X dir = strchr( set_dir, '=' ) + 1;
- X
- X if( cell->ce_attr & A_SETDIR )
- X Warning( "Multiple .SETDIR for %s ignored", cell->CE_NAME );
- X else
- X if( *dir ) cell->ce_dir = dir;
- X }
- X cell->ce_attr |= attr; /* set rest of attributes for target */
- X
- X DB_VOID_RETURN;
- X}
- X
- X
- X
- Xstatic void
- X_set_global_attr( attr, dir )/*
- X===============================
- X Handle the setting of the global attribute functions based on
- X The attribute flags set in attr. Note we set the dir path name
- X to be the value of Start_dir. If Start_dir is initially set
- X Make will CD to that directory before making any targets. */
- Xt_attr attr;
- Xchar *dir;
- X{
- X int flag;
- X
- X /* Some compilers can't handle a switch on a long, and t_attr is now a long
- X * integer on some systems. foey! */
- X for( flag = MAX_ATTR; flag; flag >>= 1 )
- X if( flag & attr )
- X if( flag == A_PRECIOUS) Def_macro(".PRECIOUS", "y", M_EXPANDED);
- X else if( flag == A_SILENT) Def_macro(".SILENT", "y", M_EXPANDED);
- X else if( flag == A_IGNORE ) Def_macro(".IGNORE", "y", M_EXPANDED);
- X else if( flag == A_EPILOG ) Def_macro(".EPILOG", "y", M_EXPANDED);
- X else if( flag == A_PROLOG ) Def_macro(".PROLOG", "y", M_EXPANDED);
- X else if( flag == A_NOINFER ) Def_macro(".NOINFER", "y", M_EXPANDED);
- X else if( flag == A_SEQ ) Def_macro(".SEQUENTIAL","y", M_EXPANDED);
- X else if( flag == A_SHELL ) Def_macro(".USESHELL", "y", M_EXPANDED);
- X else if( flag == A_MKSARGS ) Def_macro(".MKSARGS", "y", M_EXPANDED);
- X else if( flag == A_SWAP ) Def_macro(".SWAP", "y", M_EXPANDED);
- X else if( flag == A_SETDIR ) {
- X dir = strchr( dir, '=' ) + 1;
- X if( *dir ) Start_dir.ce_dir = dir;
- X }
- X
- X attr &= ~A_GLOB;
- X if( attr ) Warning( "Non global attribute(s) ignored" );
- X}
- X
- X
- X
- Xstatic void
- X_stick_at_head( how, pq )/*
- X===========================
- X Add the prerequisite list to the head of the existing prerequisite
- X list */
- X
- XHOWPTR how; /* HOW cell for target node */
- XCELLPTR pq; /* list of prerequisites to add */
- X{
- X DB_ENTER( "_stick_at_head" );
- X
- X if( pq->ce_link != NIL(CELL) ) _stick_at_head( how, pq->ce_link );
- X Add_prerequisite( how, pq, TRUE );
- X
- X DB_VOID_RETURN;
- X}
- X
- X
- X
- Xstatic t_attr
- X_is_attribute( name )/*
- X=======================
- X Check the passed name against the list of valid attributes and return the
- X attribute index if it is, else return 0, indicating the name is not a valid
- X attribute. The present attributes are defined in dmake.h as A_xxx #defines,
- X with the corresponding makefile specification: (note they must be named
- X exactly as defined below)
- X
- X Valid attributes are: .IGNORE, .SETDIR=, .SILENT, .PRECIOUS, .LIBRARY,
- X .EPILOG, .PROLOG, .LIBRARYM, .SYMBOL, .UPDATEALL,
- X .USESHELL, .NOINFER
- X
- X NOTE: The strcmp's are OK since at most three are ever executed for any
- X one attribute check, and that happens only when we can be fairly
- X certain we have an attribute. */
- Xchar *name;
- X{
- X t_attr attr = 0;
- X
- X DB_ENTER( "_is_attribute" );
- X
- X if( *name++ == '.' )
- X switch( *name )
- X {
- X case 'E': attr = (strcmp(name, "EPILOG")) ? 0 : A_EPILOG; break;
- X case 'I': attr = (strcmp(name, "IGNORE")) ? 0 : A_IGNORE; break;
- X case 'L': attr = (strcmp(name, "LIBRARY")) ? 0 : A_LIBRARY; break;
- X case 'M': attr = (strcmp(name, "MKSARGS")) ? 0 : A_MKSARGS; break;
- X case 'N': attr = (strcmp(name, "NOINFER")) ? 0 : A_NOINFER; break;
- X
- X case 'U':
- X if( !strcmp(name, "UPDATEALL") ) attr = A_UPDATEALL;
- X else if( !strcmp(name, "USESHELL")) attr = A_SHELL;
- X else attr = 0;
- X break;
- X
- X case 'P':
- X if( !strcmp(name, "PRECIOUS") ) attr = A_PRECIOUS;
- X else if( !strcmp(name, "PROLOG") ) attr = A_PROLOG;
- X else attr = 0;
- X break;
- X
- X case 'S':
- X if( !strncmp(name, "SETDIR=", 7) ) attr = A_SETDIR;
- X else if( !strcmp(name, "SILENT") ) attr = A_SILENT;
- X else if( !strcmp(name, "SYMBOL") ) attr = A_SYMBOL;
- X else if( !strcmp(name, "SEQUENTIAL")) attr = A_SEQ;
- X else if( !strcmp(name, "SWAP")) attr = A_SWAP;
- X else attr = 0;
- X break;
- X }
- X
- X DB_RETURN( attr );
- X}
- X
- X
- X
- Xstatic int
- X_is_special( tg )/*
- X===================
- X This function returns TRUE if the name passed in represents a special
- X target, otherwise it returns false. A special target is one that has
- X a special meaning to dmake, and may require processing at the time that
- X it is parsed.
- X
- X Current Special targets are:
- X .GROUPPROLOG .GROUPEPILOG .INCLUDE .IMPORT
- X .EXPORT .SOURCE .SUFFIXES .ERROR
- X .INCLUDEDIRS .MAKEFILES .REMOVE
- X*/
- Xchar *tg;
- X{
- X DB_ENTER( "_is_special" );
- X
- X if( *tg++ != '.' ) DB_RETURN( 0 );
- X
- X switch( *tg )
- X {
- X case 'I':
- X if( !strcmp( tg, "IMPORT" ) ) DB_RETURN( ST_IMPORT );
- X else if( !strcmp( tg, "INCLUDE" ) ) DB_RETURN( ST_INCLUDE );
- X else if( !strcmp( tg, "INCLUDEDIRS" )) DB_RETURN( ST_REST );
- X break;
- X
- X case 'M':
- X if( !strcmp( tg, "MAKEFILES" ) ) DB_RETURN( ST_REST );
- X break;
- X
- X case 'E':
- X if( !strcmp( tg, "ERROR" ) ) DB_RETURN( ST_REST );
- X else if( !strcmp( tg, "EXPORT" ) ) DB_RETURN( ST_EXPORT );
- X break;
- X
- X case 'G':
- X if( !strcmp( tg, "GROUPPROLOG" )) DB_RETURN( ST_REST );
- X else if( !strcmp( tg, "GROUPEPILOG" )) DB_RETURN( ST_REST );
- X break;
- X
- X case 'R':
- X if( !strcmp( tg, "REMOVE" ) ) DB_RETURN( ST_REST );
- X break;
- X
- X case 'S':
- X if( !strncmp( tg, "SOURCE", 6 ) ) DB_RETURN( ST_SOURCE );
- X else if( !strncmp(tg, "SUFFIXES", 8 )) DB_RETURN( ST_SOURCE );
- X break;
- X }
- X
- X DB_RETURN( 0 );
- X}
- X
- X
- X
- Xstatic int
- X_is_percent( np )/*
- X===================
- X return TRUE if np points at a string containing a % sign */
- Xchar *np;
- X{
- X return( (strchr(np,'%') && (*np != '\'' && np[strlen(np)-1] != '\'')) ?
- X TRUE : FALSE );
- X}
- X
- X
- Xstatic char *
- X_is_magic( np )/*
- X=================
- X return TRUE if np points at a string of the form
- X .<chars>.<chars> or .<chars>
- X where chars are only alpha characters.
- X
- X NOTE: reject target if it begins with ./ or ../ */
- Xchar *np;
- X{
- X register char *n;
- X
- X n = np;
- X if( *n != '.' ) return( NIL(char) );
- X if (strchr(DirBrkStr, *(n+1))!=NULL || *(n+1) == '.' )
- X return (NIL(char));
- X
- X for( n++; isgraph(*n) && (*n != '.'); n++ );
- X
- X if( *n != '\0' ) {
- X if( *n != '.' ) return( NIL(char) );
- X for( np = n++; isgraph( *n ) && (*n != '.'); n++ );
- X if( *n != '\0' ) return( NIL(char) );
- X }
- X else if( !Augmake )
- X return( NIL(char) );
- X
- X /* np points at the second . of .<chars>.<chars> string.
- X * if the special target is of the form .<chars> then np points at the
- X * first . in the token. */
- X
- X return( np );
- X}
- X
- SHAR_EOF
- echo "File rulparse.c is complete"
- chmod 0440 rulparse.c || echo "restore of rulparse.c fails"
- echo mkdir - readme
- mkdir readme
- echo "x - extracting readme/release (Text)"
- sed 's/^X//' << 'SHAR_EOF' > readme/release &&
- Xdmake Version 3.6
- X=================
- X
- XMANDATORY REPLACEMENT FOR VERSION 3.5 PATCH LEVEL 1 and PATCH LEVEL 2
- X
- XNature: This version of dmake MUST replace all versions of dmake 3.5 patch
- X------- levels 1 and 2, and all versions of dmake 3.5 patch level 1 and 2
- X must then be DELETED. This release addresses several issues.
- X
- X 1. Copyright infringement claim made by MKS, of Waterloo.
- X 2. Modifications to text diversion processing.
- X 3. Support for DOS Swapping, and MKS argument passing.
- X 4. Other minor nits and tweaks.
- X
- X This distribution advances dmake to Version 3.6, patch level 1. This
- X version is certified free of MKS copyrighted code. See below for
- X details.
- X
- XAvailability:
- X-------------
- X dmake is available via anonymous ftp from watmsg.uwaterloo.edu
- X (129.97.129.9) as:
- X
- X pub/src/dmake-3.6.tar.Z
- X pub/src/dmake-3.6.zoo
- X
- X and comes in either a compressed tar or zoo archive take your pick.
- X
- XAcknowledgements:
- X-----------------
- X Thanks to all who submitted code for new features, suggestions for
- X improvements, and bug fixes. Special thanks to those who helped
- X test this version of dmake on the many platforms that the
- X distribution now supports. I have tried to make sure no gotchas
- X remain, if you encounter problems installing or running dmake please
- X let me know. As always, I am always happy to receive e-mail.
- X
- X
- XDETAILS OF CHANGES:
- X===================
- X
- XMKS Copyright Infringement:
- X---------------------------
- X Due to a misunderstanding over past contractual obligations between
- X myself and Mortice Kern Systems of Waterloo, Ontario, Canada (MKS),
- X the original posting of dmake unitentionally contains some code
- X derived from MKS proprietary code.
- X
- X This version rectifies that situation and MUST replace all versions
- X of DMAKE and DMAKE patches that have been previously distributed.
- X Please delete from any archive site versions of DMAKE source code
- X labeled 3.5 patch level 1 or patch level 2 and dmake 3.5 patch 1.
- X
- X Version 3.6 of the dmake source replaces *ALL* MKS proprietary code.
- X In particular, putenv.c in the bsd43 and sysvr1 directories is new.
- X Three routines in percent.c; Add_dfa, Construct_dfa, and Advance_dfa
- X have been replaced. Lastly, TEXT DIVERSION processing has been removed
- X from make.c and <+...+> constructions are replaced by the $(mktmp ...)
- X construct (see below for more details). The changes relating to the
- X above mentioned modifications have been reviewed by MKS and certified by
- X MKS to be free of MKS proprietary code. The note below is from MKS
- X and releases dmake version 3.6 patch level 1 from any MKS copyright
- X infringement claims.
- X
- X "MKS has reviewed the latest sources, as of 90.09.20,
- X for the files make.c, putenv.c, and percent.c, which
- X are part of the program dmake version 3.6, and found
- X these files to be free of MKS proprietary source code."
- X
- X No functionality is lost as a result of these changes, however
- X certain constructs may have to be expressed using a new syntax. See
- X the documentation and the comments below for details.
- X
- X
- XText Diversion Processing:
- X--------------------------
- X As alluded to above, the <+...+> text diversion facility has been
- X officially replaced by a new facility of the form $(mktmp ...) details of
- X which may be found in the TEXT DIVERSION section of the documentation.
- X Briefly, the construct:
- X
- X exe:; link @<+$(OBJFILES:t"+\n")+>
- X
- X is replaced by:
- X
- X exe:; link @$(mktmp $(OBJFILES:t"+\n"))
- X
- X similarly the construct:
- X
- X all :
- X echo hi <+
- X line1
- X line2 +>
- X
- X is replaced by:
- X
- X all :
- X echo hi $(mktmp\
- X line1\n\
- X line2)
- X
- X where the \n\ is added to the end of each line within the data portion of
- X the $(mktmp ...) construction. For a number of reasons it is my belief
- X that this new construct is a better implementation of text diversions than
- X the previous <+...+> as it can be used in macro expressions that appear
- X anywhere in the makefile.
- X
- X Compatibility is retained for previous versions of dmake that utilize
- X a simple form of the <+...+> construct. If your <+...+> constructs do not
- X span multiple lines (cf second example above), then the new version of
- X dmke will recognize these and will map them to the appropriate
- X $(mktmp ...) construct. Thus, If you use <+...+> and you do not allow the
- X interior data to span multiple lines and both <+ and +> appear as clear
- X text in the same recipe line or macro value, then dmake will process these
- X correctly and the output is 100% compatible to version 3.5 patch level 2.
- X Any other use of <+...+> must be converted to the new $(mktmp ...) form.
- X
- X The new form also provides for massaging the name of the temporary file
- X which replaces the text in the recipe. See the documentation regarding
- X the special macros USESHELL, TMPFILE, and DIVSHELL. This is of most use
- X in an MSDOS environment.
- X
- X
- XDOS Swapping, and MKS argument passing:
- X---------------------------------------
- X dmake now supports swapping the executable image to secondary storage when
- X it executes a child. Swapping is enabled by setting the new attribute
- X .SWAP to on, either for a target or globally, or by specifying the '%'
- X modifier to a recipe line. So for example:
- X
- X xx .SWAP :; recipe
- X
- X and
- X
- X xx :;% recipe
- X
- X are equivalent.
- X
- X The MKS DOS argument passing conventions are now supported, and dmake is
- X able to communicate with programs that understand those conventions. The
- X global variable .MKSARGS is used to enable/disable this facility. With
- X these modifications, dmake now supports long command lines for running
- X commands that understand the MKS argument passing convention, and it does
- X not run into memory limitations when executing child processes in most
- X situations.
- X
- X Both .SWAP and .MKSARGS are ignored by non-MSDOS versions of dmake.
- X See the manual page for further details.
- X
- X
- XOther tweaks modifications and BUG FIXES:
- X-----------------------------------------
- X-- Slight modifications to msdos/startup.mk files. Set DIRSEPSTR to \
- X if using command.com as the shell, otherwise set internaly to /.
- X Removed -o $@ from MSC startup.mk, and added $(ASFLAGS) to %$O : %$S
- X rule, in all default DOS startup.mk files.
- X
- X-- Added POSIX '+' character to start of recipe lines. You can use this
- X to force the recipe line to be executed by a shell, in addition to the
- X test used for .SHELLMETAS.
- X
- X To make the '+' fit into the dmake mold, a new attribute has been created.
- X the .USESHELL attribute forces the use of a shell for the target or
- X recipe group for which it is specified. If it is specified as a global
- X attribute then all recipes executed will use a shell. The macro variable
- X .USESHELL corresponds to the special target '.USESHELL :' in the same way
- X that .IGNORE corresponds to '.IGNORE :'.
- X
- X-- Added *= and *:= macro assignmen operator, patches from
- X Piercarlo Grandi <pcg@compsci.aberystwyth.ac.uk>, see the documentation
- X for more details.
- X
- X-- Changed makefile.mk to force use of a shell (via '+') to make OBJDIR,
- X doesn't break on baren DOS systems that way :-). Many other small changes
- X to msdos and unix versions of various config.mk files.
- X
- X-- Added two new macros related to diversion file processing.
- X See the TEXT DIVERSIONS section of the man page for an explanation of this
- X functionality.
- X
- X TMPFILE - is set to the name of the temporary file whenever
- X a temporary file is opened by dmake.
- X USESHELL- It's value is 'no' if the current recipe line is not forced
- X to use a shell via a '+' or .USESHELL directive. It's
- X value is 'yes' if such a directive is given.
- X DIVFILE - is defined in startup.mk and gives a macro to use to set
- X name of the diversion file, (under UNIX, DIVFILE defaults to
- X $(TMPFILE), under MSDOS it is the value of $(TMPFILE) with
- X any / replaced by the appropriate number of \ depending, on
- X if a shell is used or not).
- X
- X-- \\ appearing at the end of a line does not cause a continuation to the next
- X line.
- X
- X-- Modified the definition of macro supplied from the command line to allow
- X macros defined using += or +:= to be modified further from within the
- X makefile.
- X
- X-- Added MAKETARGETS macro which contains the name of the target(s), if any,
- X specified on the command line.
- X
- X-- Modified Pack_argv in sysintf.c to use dynamic memory allocation rather
- X than limit it to a fixed number of arguments.
- X
- X-- BIG BUG FIX:
- X This one is cute. It turns out that all individual recipe line
- X attributes supplied via '@', '-', and now '+' and '%' characters were
- X getting or'ed together and applied to ALL recipe lines of the recipe, yulk!
- X
- X-- BUG FIX:
- X Fixed off by one error in make.c:_print_cmnd when remapping \n after
- X printing the text.
- X
- X-- BUG FIX: Bug reported by holos0!lbr@gatech.edu
- X Inferred prerequisites were not getting made when a target was found to
- X be out of date relative to a non-inferred prerequisite, and the inferred
- X prerequisite did not exist but the file it could be made from did and was
- X not out of date relative to the target. This was a problem with the
- X following setup.
- X
- X file.o : header.h
- X
- X File system contains file.o, header.h and RCS/file.c,v, If file.o is newer
- X than RCS/file.c,v and older than header.h, then dmake didn't check out
- X file.c prior to doing the compile.
- X
- X-- BUG FIX: Applied patch from UUCP: twc@legal or ...sun!ys2!legal!twc
- X to msdos/_chdir.c to fix changing of directory in OS/2 protected mode
- X
- X-- BUG FIX: Applied patch from UUCP: twc@legal or ...sun!ys2!legal!twc
- X to msdos/switchar.c to read environment variable SWITCHAR instead of using
- X unsupported call in DOS. OS/2 doesn't have _get_switchar call! (It damn
- X well should though! Microsoft is really dumb in this respect!)
- X
- X Extended this patch to use SWITCHAR environment variable in all DOS
- X versions. This ensures that DOS 4.0 can selectively change SWITCHAR by
- X using the environment variable.
- X
- X Dmake now first gets SWITCHAR from the environment and if that fails it
- X tries the unsupported MSDOS call. Under UNIX getswitchar returns '-'
- X as before.
- X
- X-- BUG FIX: Changed the line _ar.ar_size = atol(arhdr.ar_size) found in
- X ar_scan() in arlib.c to not use atol() if ASCARCH is FALSE. I forget who
- X reported this one :-)
- SHAR_EOF
- chmod 0640 readme/release || echo "restore of readme/release fails"
- echo "x - extracting readme/os2 (Text)"
- sed 's/^X//' << 'SHAR_EOF' > readme/os2 &&
- XAs shipped the DOS versions of dmake will run under OS/2 protected mode.
- XI have a port that works in real mode but it was based on the DOS version.
- XI would like to produce an independent OS/2 directory (cf unix) that contains
- Xall necessary files to make an OS/2 version, and to boot strap it with a
- Xcommand shell. If anyone is willing to do this I will send them the OS/2
- Xmods that need to be made.
- SHAR_EOF
- chmod 0640 readme/os2 || echo "restore of readme/os2 fails"
- echo "x - extracting readme/msdos (Text)"
- sed 's/^X//' << 'SHAR_EOF' > readme/msdos &&
- XSome notes on the MSDOS implementation of dmake.
- X
- XMaking the binary:
- X------------------
- X
- X Turbo-C: By default the turbo-C (make tcc) script will make a version
- X of the binary that is compiled for an 8088 and up cpu. Once made
- X you can make a version for a 186 or 286 by modifying
- X msdos/tccdos/config.mk and setting CFLAGS to contain the right
- X flags, comments are supplied in the makefile to do so.
- X
- X The contents of the default response files
- X (named in msdos/tccdos/mk*.bat) assume specific locations for
- X your turbo-C libraries, you may need to edit these before actually
- X getting a successful binary linked.
- X
- X Microsoft-C 4.0 to 5.1:
- X Is straight forward, just type 'make msc' and the compile will
- X chunk along.
- X
- X Microsoft-C 6.0:
- X Is equally easy, just type 'make msc60' and the compile will
- X chunk along. Once made, if you want to use dmake to compile
- X itself then set the environment variable MSC_VER=6.0, otherwise
- X the compile flags will not be correct. You may also supply this
- X as an option on the dmake command line.
- X
- X Memory Requirements and Swapping:
- X dmake requires quite a bit of memory to run. As a result
- X a swapping version of dmake is made if you issue the command
- X 'make tccswp', 'make mscswp' or 'make msc60swp'. If you leave
- X the 'swp' off then corresponding (as described above) non-swapping
- X versions are made.
- X
- X The swapping code currently only swaps to DISK, I have left hooks
- X in to accomodate XMS and EMS, I have some code that performs the
- X necessary XMS/EMS accesses but have not incorporated it in yet.
- X It appears that a ramdisk seems to work just fine. If anyone
- X wishes to fill in the hooks please do and I'll be happy to include
- X them in future distributions.
- X
- X dmake 'makefile.mk' control variables:
- X Initially dmake is compiled for the compact memory model.
- X Setting MODEL={s,c,m,l} on the command line will select a different
- X memory model. Setting NOSWAP:=1 on the command line
- X will disable the compile and linking of the swap code.
- X A summary of the available configuration variables follows:
- X
- X MODEL={s,c,m,l} - Select {small, compact, medium, large}
- X memory model respectively.
- X NOSWAP:=y - If set, do not compile the dmake
- X swapping version of spawnvpe.
- X MSC_VER:=6.0 - Must be set if using MSC 6.0 and dmake
- X is used to make a new version of dmake.
- X
- X ^C and stopping a make:
- X Handling of ^C in the swapping version seems to be somewhat
- SHAR_EOF
- echo "End of part 6"
- echo "File readme/msdos is continued in part 7"
- echo "7" > s2_seq_.tmp
- exit 0
-
-